home *** CD-ROM | disk | FTP | other *** search
- /* Copyright, 1990, Regents of the University of Colorado */
- /***************************************
- ***************************************
- ** **
- ** IPSC1 Run Time Library for DINO **
- ** **
- ***************************************
- ***************************************/
-
- #include "D_lib.h"
- #include "internal.h"
- #include "export.h"
- #include "route.h"
- #include <stdio.h>
- #if D_MACH==D_CUBE
- #include <dos/malloc.h>
- #else
- #include <malloc.h>
- #endif
- #include <ctype.h>
-
-
-
-
- /*****************************
- * *
- * Library variables. *
- * *
- *****************************/
-
- /** MY STUFF **/
- char ch[100];
-
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- int D_ci = -1; /* Channel number. */
- #endif
- envvar caller = {0,0};
- envvar D_snd_source = {0,0};
- long int D_TYPE_START = 0; /* Starting number for message types. */
- long int D_TYPE_END = 0; /* Last number for message types + 1. */
- long int D_TYPE_CURRENT = 0; /* Next message type. */
- /*envvar D_my_env = {0, 0};*/ /* The environment structure and environment
- on this node and pid. */
-
- /* This code forces the alignment of D_mess_buf */
- double D_mess_tmp [D_MAX_MESS / sizeof (double)];
- char *D_mess_buf = (char *) &D_mess_tmp [0];
-
- /* Here are the variables used by the new composite procedure stuff */
- char *D_buf = 0;
- long int D_rem = 0;
- int D_le = 0;
- int D_main_type = 0;
- int D_sub_type = 0;
- D_env_set *D_es = (D_env_set *) 0;
- int D_cp = 0;
- int D_env_size = 0;
- int D_n_envs = 0;
- D_BOOL D_first_msg = FALSE;
- int D_node;
- int D_pid;
- long int D_size;
-
- char D_mess_buf2[D_MAX_MESS];
- D_process **D_env_lookup = {0};
-
- envvar **D_process_lookup = {0};
-
- extern int D_mach_dims;
- extern int D_max_pids;
-
-
-
-
-
- /********************************************************************
- *
- * NAME: D_env_init --- Initializes the environment lookup table.
- *
- * INPUTS: A storage space descriptor, a data distribution
- * descriptor, an environment set, a data mapping
- * descriptor, a data name descriptor, and a data
- * iteration descriptor.
- *
- * OUTPUTS: The data iteration descriptor may be updated for
- * handling multiple calls.
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_env_init(num_envs)
- int num_envs;
- {
- int env;
- int mach_size;
- int I, J;
- D_env_tbl *e;
- int size = 1;
- int *work; /* Holds the number of processors in each
- dimension. */
- #if D_HOST ==0
- int hold;
- #endif
-
- mach_size = (1 << D_mach_dims);
-
- /* Allocate the outer part of both lookup tables. */
-
- if ((D_env_lookup = (D_process **) malloc((unsigned)
- (num_envs * sizeof(D_process *)))) == NULL)
- {
- #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(1, "Malloc failure in initializing environments\n\n");
- #else
- fprintf(stderr,"NODE:%d,PID:%d;Malloc failure in initializing environments \n\n",mynode(),mypid());
- #endif
- exit(1);
- }
- if ((D_process_lookup = (envvar **) malloc((unsigned)
- (mach_size * sizeof(envvar *)))) == NULL)
- {
- #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(1, "Malloc failure in initializing environments\n\n");
- #else
- fprintf(stderr,"NODE:%d,PID:%d;Malloc failure in initializing environments \n\n",mynode(),mypid());
- #endif
-
- exit(1);
- }
-
- #if D_HOST && (D_MACH==D_SIM2 || D_MACH==D_CUBE2 || D_MACH == D_CUBE860 || D_MACH==D_GRAIL)
- setpid(D_HOST_PID);
- #endif
-
- /* Compute the size of work and allocate it. */
-
-
- for (env = 0; env < num_envs; env++)
- if (D_env_table[env].n_dims > size)
- size = D_env_table[env].n_dims;
- if ((work = (int *) malloc((unsigned) (size * sizeof(int)))) == NULL)
- {
- #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(1, "Malloc failure in initializing environments\n\n");
- #else
- fprintf(stderr,"NODE:%d,PID:%d;Malloc failure in initializing environments \n\n",mynode(),mypid());
- #endif
- exit(1);
- }
-
- /* For every node on the machine: */
-
- for (I = 0; I < mach_size; I++)
- {
- /* Allocate the rest of the process lookup table. */
-
- if ((D_process_lookup[I] = (envvar *) malloc((unsigned)
- (D_max_pids * sizeof(envvar)))) == NULL)
- {
- #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(1, "Malloc failure in initializing environments\n\n");
- #else
- fprintf(stderr,"NODE:%d,PID:%d;Malloc failure in initializing environments \n\n",mynode(),mypid());
- #endif
- exit(1);
- }
-
- /* Initialize the process lookup table. */
-
- for (J = 0; J < D_max_pids; J++)
- D_process_lookup[I][J].name = -1;
- }
-
- /* For every environment structure in the program: */
-
- for (env = 0; env < num_envs; env++)
- {
- e = &D_env_table[env];
-
- /* Allocate the rest of the environment lookup table. */
-
- if ((D_env_lookup[env] = (D_process *) malloc((unsigned)
- (e->size * sizeof(D_process)))) == NULL)
- {
- #if (D_MACH==D_SIM || D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(1, "Malloc failure in initializing environments\n\n");
- #else
- fprintf(stderr,"NODE:%d,PID:%d;Malloc failure in initializing environments \n\n",mynode(),mypid());
- #endif
- exit(1);
- }
-
- /* If it is the host environment, treat it specially. */
-
- if (e->on_host)
- {
- #if (D_MACH == D_SIM2 || D_MACH == D_CUBE2 || D_MACH == D_CUBE860 || D_MACH == D_GRAIL)
- D_env_lookup[env][0].node = myhost();
- #else
- D_env_lookup[env][0].node = D_HOST_NID;
- #endif
- D_env_lookup[env][0].pid = D_HOST_PID;
- }
-
- /* Otherwise, for every environment on a node: */
-
- else
- {
- int proc;
- int pid;
- int ord;
- int lookup[64]; /* Table used to store mapping from
- up to 64 node virtual machine to
- up to 64 node physical machine. */
-
- /* If there is a full machine or larger, compute a lookup
- table for an appropriately dimensioned machine. */
-
- if (e->is_big)
- {
- int I, J, K; /* Counters. */
-
- int temp; /* Used to compute the coordinates of
- the physical node. */
- int ptemp; /* Used to compute the linearized
- position of the virtual node. */
- int hold, hold2; /* Used to compute the inverse gray code. */
- int mid, block, mpt;/* Used to select the appropriate physical
- machine node. */
- int coords[7]; /* Holds the coordinates of first the
- physical, then the virtual node. */
- int dim_limit = e->n_dims<D_mach_dims?e->n_dims:D_mach_dims;
- /* The lesser of the number of
- dimensions in the environment
- structure and the number of
- dimensions in the actual machine. */
- int t_pos; /* Position of an actual element in
- a particular dimension. */
-
- /* Compute the number of processors in each dimension. */
-
- for (J = 0; J < e->n_dims; J++)
- work[J] = 1 << e->mach_dim[J];
-
- /* For each processor in the physical machine: */
-
- for (I = 0; I < (1 << D_mach_dims); I++)
- {
-
- /* Compute its coordinates and change them
- to coordinates in the virtual machine; */
-
- temp = I;
- for (J = dim_limit - 1; J >= 0; J--)
- {
- /* Get the coordinates for this dimension. */
-
- coords[J] = temp % work[J];
- temp = temp/work[J];
-
- /* Compute their inverse gray code. */
-
- hold = coords[J]/2;
- hold2 = coords[J];
- while (hold != 0)
- {
- hold2 = hold2 ^ hold;
- hold = hold/2;
- }
- coords[J] = hold2;
- }
-
- /* Linearize the virtual machine coordinates; */
-
- ptemp = coords[0];
- for (J = 1; J < dim_limit; J++)
- ptemp = (ptemp * work[J]) + coords[J];
-
- /* Store the results in the lookup table. */
-
- lookup[ptemp] = I;
- }
-
- /* For each environment in the structure: */
-
- for (I = 0; I < e->size; I++)
- {
- /* Initialize all the variables for the
- lowest dimension. */
- t_pos = I;
- for (K = e->n_dims - 1; K > 0; K--)
- t_pos /= e->dim[K]; /* Position in this dimension.*/
- mid = e->dim[0] % work[0]; /* Number of large blocks. */
- block = e->dim[0] / work[0]; /* Size of block. */
- mpt = mid * (block + 1); /* First point small blocks. */
- if (mid == 0)
- {
- proc = t_pos / block;
- pid = t_pos % block;
- }
- else
- {
- if (t_pos > mpt)
- {
- proc = mid + (t_pos - mpt) / block;
- pid = (t_pos - mpt) % block;
- }
- else
- {
- proc = t_pos / (block + 1);
- pid = t_pos % (block + 1);
- }
- }
- /* Iterate through each subsequent dimension. */
-
- for (J = 1; J < e->n_dims; J++)
- {
- t_pos = I;
- for (K = e->n_dims - 1; K > J; K--)
- t_pos /= e->dim[K];
- t_pos %= e->dim[J];
- mid = e->dim[J] % work[J];
- block = e->dim[J] / work[J];
- mpt = mid * (block + 1);
- if (mid == 0)
- {
- proc = proc * work[J] + t_pos / block;
- pid = pid * e->pids[J] + t_pos % block;
- }
- else
- {
- if (t_pos > mpt)
- {
- proc = proc * work[J] + mid +
- (t_pos - mpt) / block;
- pid = pid * e->pids[J] + (t_pos - mpt) % block;
- }
- else
- {
- proc = proc * work[J] + t_pos / (block + 1);
- pid = pid * e->pids[J] + t_pos % (block + 1);
- }
- }
- }
- D_env_lookup[env][I].node = lookup[proc];
- D_env_lookup[env][I].pid = pid + e->pid;
- }
- }
- else
- {
- int I; /* Counter. */
-
- /* For each environment in the structure: */
-
- for (I = 0; I < e->size; I++)
- {
- ord = e->start + I;
- D_env_lookup[env][I].node = ord^(ord>>1);
- D_env_lookup[env][I].pid = e->pid;
- }
- }
- }
- #if D_HOST
- if(!e->on_host)
- {
- int pid, prod, I;
-
- #ifdef DEBUG
- {
- int Z; char enter[25];
- (void) printf("\n\n\tLoad nodes automatically?? (Y/N) -->");
- for (Z = 0; Z < 25; Z++){enter[Z] = getchar();if (enter[Z]=='\n'){enter[Z]='\0';break;}}
- if(enter[0] == 'y' || enter[0] == 'Y')
- {
- if (e->is_big)
- {
- for (I=0, prod=1; I<e->n_dims; I++)
- prod *= e->pids[I];
- for (pid = 0; pid < prod; pid++)
- load(e->name, -1, pid + e->pid);
- }
- else
- {
- if (num_envs < 3 || mach_size == e->size)
- load(e->name, -1, e->pid);
- else
- for (I = 0; I < e->size; I++)
- load(e->name, D_env_lookup[env][I].node,
- D_env_lookup[env][I].pid);
- }
- }}
- #else
- if (e->is_big)
- {
- for (I=0, prod=1; I<e->n_dims; I++)
- prod *= e->pids[I];
- for (pid = 0; pid < prod; pid++)
- load(e->name, -1, pid + e->pid);
- }
- else
- {
- if (num_envs < 3 || mach_size == e->size)
- load(e->name, -1, e->pid);
- else
- for (I = 0; I < e->size; I++)
- load(e->name, D_env_lookup[env][I].node,
- D_env_lookup[env][I].pid);
- }
- #endif
- }
- #endif
- }
- {
- int I, J, node, pid;
- int total, me, host;
- #if (D_MACH == D_SIM2 || D_MACH == D_CUBE2 || D_MACH == D_CUBE860 || D_MACH==D_GRAIL)
- int temp = myhost();
- #endif
-
- #if D_HOST
- #if (D_MACH == D_SIM2 || D_MACH == D_CUBE2 || D_MACH == D_CUBE860 || D_MACH==D_GRAIL)
- node = temp;
- #else
- node = D_HOST_NID;
- #endif
- pid = D_HOST_PID;
- #else
- pid = mypid();
- node = mynode();
- #endif
-
- D_my_env.index = -1;
- total = 0;
- for(I = 0; I < num_envs; I++)
- {
- for (J = 0; J < D_env_table[I].size; J++)
- {
- if (!D_env_table[I].on_host)
- {
- D_process_lookup[D_env_lookup[I][J].node]
- [D_env_lookup[I][J].pid].name = I;
- D_process_lookup[D_env_lookup[I][J].node]
- [D_env_lookup[I][J].pid].index = J;
- }
- if (D_env_lookup[I][J].node == node &&
- D_env_lookup[I][J].pid == pid)
- {
- D_my_env.name = I;
- D_my_env.index = J;
- me = total + J;
- }
- #if (D_MACH == D_SIM2 || D_MACH == D_CUBE2 || D_MACH == D_CUBE860 || D_MACH==D_GRAIL)
- if (D_env_lookup[I][J].node == temp)
- #else
- if (D_env_lookup[I][J].node == D_HOST_NID)
- #endif
- host = total + J;
- }
- total += D_env_table[I].size;
- }
- if (me > host)
- me--;
- size = D_TYPE_BLOCK_SIZE / total;
- if (D_HOST)
- {
- D_TYPE_START = (total - 1) * size + D_TYPE_BLOCK_START;
- D_TYPE_END = D_TYPE_START + size + (D_TYPE_BLOCK_SIZE % total);
- D_TYPE_CURRENT = D_TYPE_START;
- }
- else
- {
- D_TYPE_START = me * size + D_TYPE_BLOCK_START;
- D_TYPE_END = D_TYPE_START + size;
- D_TYPE_CURRENT = D_TYPE_START;
- }
- }
-
- #if D_HOST
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- D_ci = copen(D_HOST_PID); /*initialize THE channel*/
- #endif
- /* FUNKY DIAGNOSTICS
- pr_env_tables(2);
- END FUNKY DIAGNOSTICS */
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- D_ci = copen(mypid()); /*initialize THE channel*/
- #endif
- if (D_my_env.index == -1)
- exit(0);
- hold = D_my_env.index;
- for (I = D_env_table[D_my_env.name].n_dims - 1; I >= 0 ; I--)
- {
- *(D_local_env_table[I]) = hold % D_env_table[D_my_env.name].dim[I];
- hold = hold / D_env_table[D_my_env.name].dim[I];
- }
- #endif
-
- /* Free the intermediate data structure. */
-
- free((char *) work);
- }
-
-
- /********************************************************************
- *
- * NAME: D_lib_recvs --- Receives one or more messages
- * necessary to fill in a piece of data. Assumes
- * the storage space exists and is of the correct
- * type.
- *
- * INPUTS: A storage space descriptor, a data distribution
- * descriptor, an environment set, a data mapping
- * descriptor, a data name descriptor, and an
- * environment set.
- *
- * OUTPUTS:
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_lib_recvs(P_ssd, P_es, P_ddd, P_dmd, P_dnd, P_sync, P_data)
- D_storage_space_desc *P_ssd;
- D_env_set *P_es;
- D_data_distribution_desc *P_ddd;
- D_data_mapping_desc *P_dmd;
- D_data_name_desc *P_dnd;
- D_data_holder *P_data;
- D_BOOL P_sync;
- {
- int I, J, K, M;
- long int counter;
- D_np *D_env; /* Array of environments. */
- int count;
- int env_count = 0;
- int this_env;
- D_BOOL empty = FALSE;
- int which;
- int type;
- long int size;
- int header_size;
- register char *bufptr, *dataptr;
- char *tmpptr;
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- char *tmpptr2;
- #endif
- int cnt, node, pid, dsize;
-
- /* if the dmd has not been converted to node form, do so. */
-
- if (P_es->implicit && (! P_dmd->converted))
- map_transform(P_dmd, D_my_env.index, P_data->a);
-
- /* Initial analysis */
-
- /* Calculate the total number of environments. */
-
- /* For each environment structure: */
-
- for (I = 0; I < P_es[0].count; I++)
- {
- K = 1;
- /* Calculate its size. */
-
- for (J = 0; J < D_env_table[P_es[I].name].n_dims; J++)
- K *= D_env_table[P_es[I].name].dim[J];
-
- /* If it has a bitmap, count the true bits. */
-
- if (! (P_es[I].implicit || P_es[I].allflag))
- {
- count = 0;
- for (M = 0; M < K; M++)
- if (P_es[I].bitmap[M])
- count++;
- env_count += count;
- }
- /* Otherwise add its whole size to the total. */
- else
- env_count += K;
- }
- /* Set up the array. */
-
- D_env = P_data->e;
- if (P_es->implicit)
- D_env->total = env_count;
- else
- D_env->total = 1;
-
- /* Initialize the array. */
-
- for (I = 0; I < D_env->total; I++)
- {
- D_env[I].total = D_env->total;
- D_env[I].name = P_es->name;
- D_env[I].index = I;
- D_env[I].implicit = P_es->implicit;
- D_env[I].done = FALSE;
- D_env[I].node = D_env_lookup[P_es->name][I].node;
- D_env[I].pid = D_env_lookup[P_es->name][I].pid;
- D_env[I].parts = 0;
- D_env[I].offset = 0;
- D_env[I].size[0] = 0;
- }
-
- /* Compute sizes and internal dnd's. */
-
- if (D_env->name == D_my_env.name)
- this_env = D_my_env.index;
- else
- this_env = -1;
- get_size(P_ssd, P_ddd, P_dmd, P_dnd, D_env,
- this_env, FALSE, 0, FALSE, P_data->a, P_data->n);
-
- /* If there is nothing to be received,
- issue an error message and exit the function. */
-
- if (D_env->total == 0)
- {
- #if (D_MACH==D_SIM)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit receive called for data that is only home data.\n",
- D_my_env.name,D_my_env.index);
- #endif
- #if (D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(mypid(), "Implicit receive called for data that is only home data.");
- #endif
- #if (D_MACH==D_CUBE2)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit receive called for data that is only home data.\n",
- D_my_env.name,D_my_env.index);
- #endif
- #if (D_MACH==D_CUBE860)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit receive called for data that is only home data.\n",
- D_my_env.name,D_my_env.index);
- #endif
- return;
- }
-
- /* For each environment, compute whether or not
- it needs a header and the size of that header.*/
-
- for (I = 0; I < D_env->total; I++)
- if (D_env[I].size[0] > 0)
- {
- if (P_dnd->simple)
- {
- if (D_env[I].size[0] > D_MAX_MESS)
- {
- D_env[I].header = D_PM_HD_SZ + D_MP_HD_SZ +
- 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ;
- }
- else
- {
- D_env[I].header = 0;
- }
- }
- else
- D_env[I].header = D_PM_HD_SZ + D_MP_HD_SZ +
- 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ +
- (1 + 2 * P_dnd->dims) * sizeof(long int);
- }
-
- /* end initial analysis. */
-
- /***** MAIN LOOP *****/
-
- I = 0;
- for (;;)
- {
- which = get_message(D_env, P_sync, P_es, &dsize);
- if (which >= 0)
- {
- if (D_env[which].mess != D_NULL)
- {
- if (D_env[which].desc->dims == 0 &&
- D_env[which].size[0] <= D_MAX_MESS)
- {
- D_env[which].parts = 1;
- size = D_env[which].size[0];
- bufptr = D_env[which].mess;
- }
- else
- {
- D_env[which].parts = ((long int *) D_env[which].mess)[0];
- bufptr = D_env[which].mess + D_PM_HD_SZ + D_MP_HD_SZ;
- bufptr += *((long int *) bufptr) + D_LM_HD_SZ;
- bufptr += *((long int *) bufptr) + sizeof(long int);
- bufptr += *((long int *) bufptr) + 2 * sizeof(long int);
- header_size = bufptr - D_env[which].mess;
- size = (((D_env[which].size[0] + header_size) >
- D_MAX_MESS)?D_MAX_MESS - header_size:
- D_env[which].size[0]);
- }
- if (D_env[which].contig[0])
- {
- dataptr = D_env[which].loc[0];
- for (counter = 0; counter < size; counter++)
- *(dataptr++) = *(bufptr++);
- D_env[which].offset += size;
- }
- else
- {
- if (D_env[which].implicit)
- map_select(P_ddd, P_dmd, D_my_env.index,
- D_env[which].index, FALSE, FALSE,
- P_data->a, D_env[which].clist[0]);
- else
- ddd_xform(P_ssd, P_ddd, D_env[which].clist[0]);
- tmpptr = bufptr;
- copy_data(P_ssd, D_env[which].clist[0],
- size, &tmpptr, FALSE);
- D_env[which].offset += size;
- }
- if (D_env[which].mess != D_mess_buf)
- B_free(D_env[which].mess);
- if (D_env[which].parts > 1)
- {
- type = ((long int *) D_env[which].mess)[1];
- for (J = 1; J < D_env[which].parts; J++)
- {
- bufptr = &(D_mess_buf[0]);
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- tmpptr2 = bufptr;
- D_recvh(D_ci, type, &tmpptr2, D_MAX_MESS,
- &cnt, &node, &pid);
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- recvw(D_ci, type, &(D_mess_buf[0]), D_MAX_MESS,
- &cnt, &node, &pid);
- #else
- crecv((long)type, &(D_mess_buf[0]),(long)D_MAX_MESS);
- #endif
- #endif
- size = (((D_env[which].size[0] - D_env[which].offset) >
- D_MAX_MESS)?D_MAX_MESS:D_env[which].size[0] -
- D_env[which].offset);
- if (D_env[which].contig[0])
- {
- dataptr = D_env[which].loc[0] +
- D_env[which].offset;
- for (counter = 0; counter < size; counter++)
- *(dataptr++) = *(bufptr++);
- D_env[which].offset += size;
- }
- else
- {
- tmpptr = bufptr;
- copy_data(P_ssd, D_env[which].clist[0], size,
- &tmpptr, FALSE);
- D_env[which].offset += size;
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- if (tmpptr2 != &(D_mess_buf[0]))
- B_free(bufptr);
- #endif
- }
- }
- }
- }
- if (! P_es->implicit)
- break;
- }
- if (P_sync)
- {
- I++;
- if (I == D_env->total)
- break;
- }
- else
- {
- if (which < 0)
- {
- if (empty)
- break;
- else
- {
- for (J = 0; J < D_env->total; J++)
- D_env[J].done = FALSE;
- empty = TRUE;
- }
- }
- else
- empty = FALSE;
- }
- }
- }
-
-
-
- /********************************************************************
- *
- * NAME: D_lib_send --- Sends any one of a variety of messages.
- *
- * INPUTS: A storage space descriptor, a data distribution
- * descriptor, an environment set, a data mapping
- * descriptor, a data name descriptor, and a data
- * iteration descriptor.
- *
- * OUTPUTS: The data iteration descriptor may be updated for
- * handling multiple calls.
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_lib_send(P_ssd, P_es, P_ddd, P_dmd, P_dnd, P_data)
- D_storage_space_desc *P_ssd;
- D_env_set *P_es;
- D_data_distribution_desc *P_ddd;
- D_data_mapping_desc *P_dmd;
- D_data_name_desc *P_dnd;
- D_data_holder *P_data;
- {
- /* Function variables */
-
- static D_BOOL first = TRUE; /* Is this the first of an iterative message? */
- int D_current_env; /* Current environment. */
- static int D_part_num = 1; /* Maximum number of parts
- involved in a message. */
- int D_current_part; /* Current part. */
- static int D_sub_type; /* Type for subsequent parts of message. */
- D_np *D_env; /* Array of environments. */
- char *bufptr, *dataptr; /* Pointers to various message buffers. */
- char *buf; /* The message buffer used for this message. */
- int env_count = 0;
- int size; /* Temporary storage for message size. */
- int temp_size;
- long int bufsize; /* Size of temporary buffer. */
- char *charp; /* Pointers used to construct buffer. */
- int I, J, K, M, count; /* Index variables. */
- long int temp[5]; /* Array used to construct headers. */
- int this_env; /* Index of this environment. */
- D_BOOL working;
- int node, pid;
-
-
- /* if the dmd has not been converted to node form, do so. */
-
- if (P_es->implicit && (! P_dmd->converted))
- map_transform(P_dmd, D_my_env.index, P_data->a);
-
- /* Initial analysis */
-
- if (first)
- {
- /* Set up the environment array. */
-
- for (I = 0; I < P_es[0].count; I++)
- {
- K = 1;
- for (J = 0; J < D_env_table[P_es[I].name].n_dims; J++)
- K *= D_env_table[P_es[I].name].dim[J];
- if (! (P_es[I].implicit || P_es[I].allflag))
- {
- count = 0;
- for (M = 0; M < K; M++)
- if (P_es[I].bitmap[M])
- count++;
- env_count += count;
- }
- else
- env_count += K;
- }
- D_env = P_data->e;
- if (P_es->implicit)
- D_env->total = env_count;
- else
- D_env->total = 1;
-
- for (I = 0; I < D_env->total; I++)
- {
- D_env[I].total = D_env->total;
- D_env[I].name = P_es->name;
- D_env[I].index = I;
- D_env[I].implicit = P_es->implicit;
- D_env[I].done = FALSE;
- D_env[I].node = D_env_lookup[P_es->name][I].node;
- D_env[I].pid = D_env_lookup[P_es->name][I].pid;
- D_env[I].parts = 0;
- D_env[I].offset = 0;
- D_env[I].size[0] = 0;
- }
-
- /* Call function that computes sizes, locations,
- and contiguities for each environment. */
-
- if (D_env->name == D_my_env.name)
- this_env = D_my_env.index;
- else
- this_env = -1;
- get_size(P_ssd, P_ddd, P_dmd, P_dnd, D_env,
- this_env, TRUE, 0, FALSE, P_data->a, P_data->n);
-
- /* If there is nothing to be sent,
- issue an error message and exit the function. */
-
- if (D_env->total == 0)
- {
- #if (D_MACH==D_SIM)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit send called for data that has no copies.\n",
- D_my_env.name,D_my_env.index);
- #endif
- #if (D_MACH==D_CUBE || D_MACH==D_GRAIL)
- syslog(mypid(), "Implicit send called for data that has no copies.");
- #endif
- #if (D_MACH==D_CUBE2)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit send called for data that has no copies.\n",
- D_my_env.name,D_my_env.index);
- #endif
- #if (D_MACH==D_CUBE860)
- fprintf(stderr,
- "ENV:%d,INDEX:%d;Implicit send called for data that has no copies.\n",
- D_my_env.name,D_my_env.index);
- #endif
- return;
- }
- /* For each environment, compute whether or not
- it needs a header and the number of parts
- it needs. Determine if a temporary buffer
- is needed and what its size should be.
- Determine what the maximum number of
- message parts will be.*/
-
- for (I = 0; I < D_env->total; I++)
- if (D_env[I].size[0] > 0)
- {
- if (P_dnd->simple)
- {
- if (D_env[I].size[0] > D_MAX_MESS)
- {
- D_env[I].header = D_PM_HD_SZ + D_MP_HD_SZ +
- 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ;
- bufsize = D_MAX_MESS;
- D_env[I].parts = (D_env[I].size[0] + D_env[I].header) /
- D_MAX_MESS + (((D_env[I].size[0] +
- D_env[I].header) % D_MAX_MESS)?1:0);
- if (D_env[I].parts > D_part_num)
- D_part_num = D_env[I].parts;
- }
- else
- {
- D_env[I].header = 0;
- if (! D_env[I].contig[0])
- {
- if (bufsize < D_env[I].size[0])
- bufsize = D_env[I].size[0];
- }
- D_env[I].parts = 1;
- }
- }
- else
- {
- D_env[I].header = D_PM_HD_SZ + D_MP_HD_SZ +
- 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ +
- (1 + 2 * P_dnd->dims) * sizeof(long int);
- if (D_env[I].size[0] + D_env[I].header > D_MAX_MESS)
- {
- bufsize = D_MAX_MESS;
- D_env[I].parts = (D_env[I].size[0] + D_env[I].header) /
- D_MAX_MESS + (((D_env[I].size[0] +
- D_env[I].header) % D_MAX_MESS)?1:0);
- if (D_env[I].parts > D_part_num)
- D_part_num = D_env[I].parts;
- }
- else
- {
- if (bufsize < D_env[I].size[0] + D_env[I].header)
- bufsize = D_env[I].size[0] + D_env[I].header;
- D_env[I].parts = 1;
- }
- }
- }
-
- /* If there will be more than one part to
- any message, get a message type
- number for the subsequent parts. */
-
- if (D_part_num > 1)
- D_sub_type = get_type();
-
-
- } /* end initial analysis. */
-
- /***** MAIN LOOP *****/
-
- /***** For each part of a library created multi-part message: */
-
- for (D_current_part = 0; D_current_part < D_part_num; D_current_part++)
- {
-
- /***** For each environment involved in the message: */
-
- for (D_current_env = 0; D_current_env < D_env->total; D_current_env++)
- {
- if (D_env[D_current_env].clist[0]->dims == -1)
- {
- if (! D_env[D_current_env].contig[0])
- {
- if (D_env[D_current_env].implicit)
- map_select(P_ddd, P_dmd, D_my_env.index,
- D_env[D_current_env].index, TRUE, FALSE,
- P_data->a, D_env[D_current_env].clist[0]);
- else
- ddd_xform(P_ssd, P_ddd, D_env[D_current_env].clist[0]);
- }
- }
-
- /***** If this environment has this part: */
-
- if (D_env[D_current_env].parts > D_current_part)
- {
- buf = bufptr = &(D_mess_buf[0]);
-
- /***** Compute new message size if necessary. */
-
- size = ((D_env[D_current_env].parts - 1) > D_current_part)?
- (D_MAX_MESS - (D_current_part == 0?
- D_env[D_current_env].header:0)):
- (D_env[D_current_env].size[0] -
- D_env[D_current_env].offset);
-
- /***** If we need a header: */
-
- if ((D_env[D_current_env].header > 0) && (D_current_part == 0))
- {
- /* Physical message header. */
-
- temp[0] = D_env[D_current_env].parts;
- if (temp[0] > 1)
- temp[1] = D_sub_type;
- else
- temp[1] = 0;
- charp = (char *) temp;
- for (I = 0; I < 2 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Message Package Header. */
-
- temp[0] = 1;
- temp[1] = D_my_env.name;
- temp[2] = D_my_env.index;
- temp[3] = 2 * sizeof(long int);
- temp[4] = 3;
- charp = (char *) temp;
- for (I = 0; I < 5 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Logical message header. */
-
- temp[0] = D_env[D_current_env].header -
- (D_PM_HD_SZ + D_MP_HD_SZ + 2 * sizeof(long int)) +
- size;
- temp[1] = 1;
- temp[2] = 2 * sizeof(long int);
- temp[3] = 3;
- charp = (char *) temp;
- for (I = 0; I < 4 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Logical message element header. */
-
- temp[0] = 1;
- if (P_dnd->simple)
- {
- temp[1] = 0;
- temp_size = 3 * sizeof(long int);
- }
- else
- {
- temp[1] = (1 + D_env[D_current_env].desc->dims * 2) *
- sizeof(long int);
- temp[3] = D_env[D_current_env].desc->dims;
- temp_size = 4 * sizeof(long int);
- }
- temp[2] = size;
- charp = (char *) temp;
- for (I = 0; I < temp_size; I++)
- *(bufptr++) = *(charp++);
- if (! P_dnd->simple)
- {
- charp = (char *) D_env[D_current_env].desc->range;
- for (I = 0; I < D_env[D_current_env].desc->dims * 2 *
- sizeof(long int); I++)
- *(bufptr++) = *(charp++);
- }
-
- } /* end header setup. */
-
-
- /***** If this pass involves new data: */
-
- if ((! P_dmd->allflag) || (D_current_env == 0))
- {
- if (D_env[D_current_env].header ||
- (! D_env[D_current_env].contig[0]))
- {
- if (! D_env[D_current_env].contig[0])
- (void) copy_data(P_ssd,
- D_env[D_current_env].clist[0],
- (long int) size, &bufptr, TRUE);
- else
- {
- dataptr = D_env[D_current_env].loc[0] +
- D_env[D_current_env].offset;
- for (I = 0; I < size; I++)
- *(bufptr++) = *(dataptr++);
- }
- }
- else
- buf = D_env[D_current_env].loc[0] +
- D_env[D_current_env].offset;
- }
- else
- if (! D_env[D_current_env].header &&
- D_env[D_current_env].contig[0])
- buf = D_env[D_current_env].loc[0] +
- D_env[D_current_env].offset;
-
- D_env[D_current_env].offset += size;
-
-
- /***** Send the message. */
-
- working = TRUE;
- if (P_es->implicit)
- {
- node = D_env[D_current_env].node;
- pid = D_env[D_current_env].pid;
- }
- else
- {
- I = 0;
- env_count = D_env_table[P_es->name].size;
- for (J = 0; J < env_count; J++)
- if (P_es->allflag || P_es->bitmap[J])
- break;
- node = D_env_lookup[P_es->name][J].node;
- pid = D_env_lookup[P_es->name][J].pid;
- }
-
- do
- {
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendmsg(D_ci,
- (D_current_part == 0?
- D_env[D_current_env].desc->type:D_sub_type),
- buf, (int) (D_env[D_current_env].header &&
- D_current_part == 0?
- size+D_env[D_current_env].header:size),
- node, pid);
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendw(D_ci,
- (D_current_part == 0?
- D_env[D_current_env].desc->type:D_sub_type),
- buf, (int) (D_env[D_current_env].header &&
- D_current_part == 0?
- size+D_env[D_current_env].header:size),
- node, pid);
- #else
- csend((long)(D_current_part == 0?
- D_env[D_current_env].desc->type:D_sub_type),
- buf, (long) (D_env[D_current_env].header &&
- D_current_part == 0?
- size+D_env[D_current_env].header:size),
- (long)node,(long)pid);
- #endif
- #endif
- if (P_es->implicit)
- {
- working = FALSE;
- }
- else
- {
- J++;
- if (! P_es[I].allflag)
- for (; ! P_es[I].bitmap[J] && J < env_count; J++);
- if (J == env_count)
- {
- I++;
- if (I < P_es->count)
- {
- env_count = D_env_table[P_es[I].name].size;
- for (J = 0; J < env_count; J++)
- if (P_es[I].allflag || P_es[I].bitmap[J])
- break;
-
- }
- else
- {
- working = FALSE;
- }
- }
- if (working)
- {
- node = D_env_lookup[P_es[I].name][J].node;
- pid = D_env_lookup[P_es[I].name][J].pid;
- }
- }
- }
- while(working);
-
-
- /* FUNKY DIAGNOSTICS
- pr_mess(buf);
- END FUNKY DIAGNOSTICS */
-
- } /* end part check. */
-
- } /* end environment loop. */
-
- } /* end part loop. */
-
-
- /* Set or reset global variables as needed. */
-
- if (FALSE)
- {
- first = FALSE;
- }
- else
- {
- first = TRUE;
- }
- }
-
-
- /********************************************************************
- *
- * NAME: D_isend_init --- Does the setup for an iterative send.
- *
- * INPUTS: A pointer to the buffer, the size of the buffer,
- * an uninitialized storage space descriptor, a data
- * distribution descriptor, an environment set, a data
- * mapping descriptor, a data name descriptor, and pointers
- * to data message types for the first and subsequent messages.
- *
- * OUTPUTS: The header (if any) is placed in the buffer, the ssd
- * is initialized for the free part of the buffer, and
- * the message types are filled in.
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_isend_init(P_buf, P_size, P_elem_size, P_ssd, P_es,
- P_ddd, P_dmd, P_dnd, P_start, P_rest)
- char *P_buf; /* Pointer to new buffer */
- int P_size; /* Size of the new buffer */
- int P_elem_size; /* Size of the basic data element */
- D_storage_space_desc *P_ssd;
- D_env_set *P_es; /* Not used here */
- D_data_distribution_desc *P_ddd;/* Not used here */
- D_data_mapping_desc *P_dmd; /* Not used here */
- D_data_name_desc *P_dnd;
- int *P_start; /* Type of initial message */
- int *P_rest; /* Type of all subsequent messages */
- {
- int I;
- long int size = 0;
- D_BOOL multiple = FALSE;
- char *charp;
- char *bufptr = P_buf;
- long int temp[5];
- int header;
- int temp_size;
-
- for (I = 0; I < P_dnd->dims; I++)
- size *= (P_dnd->range[I].last - P_dnd->range[I].first + 1);
- size *= P_elem_size;
-
- *P_start = (*P_dnd->type)(P_dnd->range);
-
- header = D_PM_HD_SZ + D_MP_HD_SZ + 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ +
- (P_dnd->simple?0:((1 + 2 * P_dnd->dims) * sizeof(long int)));
- if ((size + header) > D_MAX_MESS)
- {
- multiple = TRUE;
- *P_rest = get_type();
- }
-
- if (multiple || ! P_dnd->simple)
- {
- /* Physical message header. */
-
- temp[0] = multiple?0:1;
- if (multiple)
- temp[1] = *P_rest;
- else
- temp[1] = 0;
- charp = (char *) temp;
- for (I = 0; I < 2 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Message Package Header. */
-
- temp[0] = 1;
- temp[1] = D_my_env.name;
- temp[2] = D_my_env.index;
- temp[3] = 2 * sizeof(long int);
- temp[4] = 3;
- charp = (char *) temp;
- for (I = 0; I < 5 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Logical message header. */
-
- temp[0] = header - (D_PM_HD_SZ + D_MP_HD_SZ + 2 * sizeof(long int)) +
- size;
- temp[1] = 1;
- temp[2] = 2 * sizeof(long int);
- temp[3] = 3;
- charp = (char *) temp;
- for (I = 0; I < 4 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
-
- /* Logical message element header. */
-
- temp[0] = 1;
- if (P_dnd->simple)
- {
- temp[1] = 0;
- temp_size = 3 * sizeof(long int);
- }
- else
- {
- temp[1] = (1 + P_dnd->dims * 2) * sizeof(long int);
- temp[3] = P_dnd->dims;
- temp_size = 4 * sizeof(long int);
- }
- temp[2] = size;
- charp = (char *) temp;
- for (I = 0; I < temp_size; I++)
- *(bufptr++) = *(charp++);
- if (! P_dnd->simple)
- {
- charp = (char *) P_dnd->range;
- for (I = 0; I < P_dnd->dims * 2 * sizeof(long int); I++)
- *(bufptr++) = *(charp++);
- }
- } /* end header setup. */
- else
- {
- header = 0;
- }
- P_ssd->loc = bufptr;
- P_ssd->size = size - header;
- }
-
-
-
- /********************************************************************
- *
- * NAME: D_lib_isend --- Does sends for multipart (iterative)
- * explicit messages where compiler makes a call for
- * each part.
- *
- * INPUTS: A pointer to the buffer, the message type of this
- * message, a storage space descriptor, a data
- * distribution descriptor, an environment set, a data
- * mapping descriptor, and a data name descriptor.
- *
- * OUTPUTS: The messager is sent and the storage space descriptor
- * is updated for the currently empty buffer.
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_lib_isend(P_buf, P_type, P_ssd, P_es, P_ddd, P_dmd, P_dnd)
- char *P_buf; /* Pointer to new buffer */
- int P_type; /* type of this message */
- D_storage_space_desc *P_ssd; /* Gives start and length of buffer
- on return */
- D_env_set *P_es; /* Gives environment(s) message is going to */
- D_data_distribution_desc *P_ddd;/* Not used here */
- D_data_mapping_desc *P_dmd; /* Not used here */
- D_data_name_desc *P_dnd; /* Not used here */
- {
- int I, J;
- int node, pid;
-
- if (P_buf != P_ssd->loc)
- {
- P_ssd->size += P_ssd->loc - P_buf;
- P_ssd->loc = P_buf;
- }
-
- for (I = 0; I < P_es->count; I++)
- for (J = 0; J < D_env_table[P_es->name].size; J++)
- if (P_es[I].allflag || P_es[I].bitmap[J])
- {
- node = D_env_lookup[P_es->name][J].node;
- pid = D_env_lookup[P_es->name][J].pid;
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendmsg(D_ci, P_type, P_ssd->loc, (int) P_ssd->size, node, pid);
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendw(D_ci, P_type, P_ssd->loc, (int) P_ssd->size, node, pid);
- #else
- csend((long)P_type, P_ssd->loc, (long) P_ssd->size,
- (long)node, (long)pid);
- #endif
- #endif
- }
-
- }
-
-
- /********************************************************************
- *
- * NAME: D_lib_irecv --- Does a receive of a multipart
- * (iterative) explicit message where the compiler
- * makes a call to this function for each part.
- *
- * INPUTS: A message type for this message ("0" for the first
- * part, then whatever was returned by the call for the
- * first part for the rest), storage space descriptor,
- * a data distribution descriptor, an environment set,
- * a data mapping descriptor, a data name descriptor,
- * and an environment set.
- *
- * OUTPUTS: The storage space descriptor is filled in for the
- * current buffer, the type is filled in for future
- * receives.
- *
- * NOTES: See the formal interface description for more
- * information.
- *
- ********************************************************************/
-
- void D_lib_irecv(P_type, P_elem_size, P_ssd, P_es,
- P_ddd, P_dmd, P_dnd, P_sync, P_data)
- int *P_type; /* Type of this message */
- int P_elem_size; /* Size of basic data element. */
- D_storage_space_desc *P_ssd; /* Set to buffer start and length on return */
- D_env_set *P_es; /* Gives environment(s) message
- is coming from */
- D_data_distribution_desc *P_ddd;/* Not used here */
- D_data_mapping_desc *P_dmd; /* Not used here */
- D_data_name_desc *P_dnd;
- D_BOOL P_sync; /* Not used here. */
- D_data_holder *P_data; /* Need the env_array. */
- {
- int I;
- D_BOOL multiple = FALSE;
- int size;
- D_np *env;
- int cnt, node, pid;
- char *tmptr;
- long int *temp;
-
-
- if (*P_type == 0)
- {
- env = P_data->e;
- env->total = 1;
- env->implicit = FALSE;
- env->done = FALSE;
- env->contig[0] = TRUE;
- env->loc[0] = &(D_mess_buf[0]);
- env->size[0] = 1;
-
- env->desc[0].type = (*P_dnd->type)(P_dnd->range);
- if (P_dnd->simple)
- env->desc[0].dims = 0;
- else
- {
- env->desc[0].dims = P_dnd->dims;
- for (I = 0; I < P_dnd->dims; I++)
- {
- env->desc[0].range[I].first = P_dnd->range[I].first;
- env->desc[0].range[I].last = P_dnd->range[I].last;
- }
- }
-
- for (I = 0; I < P_dnd->dims; I++)
- env->size[0] *= (P_dnd->range[I].last - P_dnd->range[I].first + 1);
- env->size[0] *= P_elem_size;
-
- env->header = D_PM_HD_SZ + D_MP_HD_SZ + 2 * sizeof(long int) + D_LM_HD_SZ +
- 2 * sizeof(long int) + D_LME_DATA_HD_SZ +
- (P_dnd->simple?0:((1 + 2 * P_dnd->dims) * sizeof(long int)));
- if (env->size[0] + (P_dnd->simple?0:env->header) > D_MAX_MESS)
- multiple = TRUE;
- if (! multiple && P_dnd->simple)
- env->header = 0;
-
- (void) get_message(env, TRUE, P_es, &size);
-
- if (multiple)
- {
- temp = (long int *) &(D_mess_buf[0]);
- *P_type = temp[1];
- }
-
- P_ssd->size = size - env->header;
- P_ssd->loc = &(D_mess_buf[0]) + env->header;
- }
- else
- {
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- tmptr = &(D_mess_buf[0]);
- D_recvh(D_ci, *P_type, &tmptr, D_MAX_MESS, &cnt, &node, &pid);
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- recvw(D_ci, *P_type, &(D_mess_buf[0]), D_MAX_MESS, &cnt, &node, &pid);
- #else
- crecv((long)*P_type, &(D_mess_buf[0]),(long)D_MAX_MESS);
- #endif
- #endif
- P_ssd->size = cnt;
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- if (tmptr != &(D_mess_buf[0]))
- {
- D_mem_copy(&(D_mess_buf[0]), tmptr, P_ssd->size);
- B_free(tmptr);
- }
- #endif
- P_ssd->loc = &(D_mess_buf[0]);
- }
- }
-
- /***********************************************************/
- /* This is the new stuff for handling composite procedures */
- /***********************************************************/
-
- int D_lib_cpc_a_init (cp_id, es)
- int cp_id;
- D_env_set *es;
-
- {
- D_le = -1;
- D_es = es;
- D_cp = cp_id;
- D_env_size = D_env_table [es->name].size;
- D_main_type = D_CPC_MTYPE;
- D_sub_type = 0;
- return (get_type());
- }
-
- D_BOOL D_lib_cpc_a_next (return_type)
- int return_type;
-
- {
- /* Find the next environment to do */
- do {
- D_le++;
- if (D_es->allflag || D_es->implicit || D_es->bitmap[D_le])
- break;
- } while (D_le < D_env_size);
-
- /* Exit if we're done */
- if (D_le == D_env_size)
- return (FALSE);
-
- /* Set up info on whom to send the message to */
- D_node = D_env_lookup [D_es->name][D_le].node;
- D_pid = D_env_lookup [D_es->name][D_le].pid;
-
- /* Set up the header for the message */
- D_mess_lint [0] = 12345;
- D_mess_lint [1] = D_my_env.name;
- D_mess_lint [2] = D_my_env.index;
- D_mess_lint [3] = D_cp;
- D_mess_lint [4] = return_type;
-
- /* Set up D_rem and D_buf */
- D_buf = (char *) (&D_mess_lint[5]);
- D_rem = D_MAX_MESS - 5 * sizeof (long int);
-
- /* Set up the message typeing stuff */
- D_first_msg = TRUE;
-
- /* That's it */
- return (TRUE);
- }
-
- void D_lib_cpr_a_init (es)
- D_env_set *es;
-
- {
- int who;
-
- /* Get D_env_size set up right again ... it could be destroyed by
- an :: operator in the original Dino program */
- D_env_size = D_env_table [es->name].size;
-
- /* Count up the number of environments in this call */
- D_n_envs = 0;
- for (who = 0; who < D_env_size; who++)
- if (es->allflag || es->implicit || es->bitmap[who])
- D_n_envs++;
-
- /* That's it! */
- }
-
- D_BOOL D_lib_cpr_a_next (return_type)
- int return_type;
-
- {
- /* See if there's a next environment to do */
- if (D_n_envs-- == 0)
- return (FALSE);
-
- /* Read in the message */
- D_main_type = return_type;
- D_first_msg = TRUE;
- D_lib_refresh_buf();
-
- /* Get D_le out of the header */
- D_le = D_mess_lint [1];
-
- /* Skip over the header */
- D_buf = (char *) (&D_mess_lint[2]);
- D_rem = D_MAX_MESS - 2 * sizeof (long int);
-
- /* That's it! */
- return (TRUE);
- }
-
- int D_lib_cpc_f_init ()
-
- {
- /* Pickup the future message type */
- D_sub_type = D_mess_lint [0];
-
- /* Set up D_buf and D_rem */
- D_buf = (char *) (&D_mess_lint[5]);
- D_rem = D_MAX_MESS - 5 * sizeof (long int);
-
- /* Set up caller */
- caller.name = D_mess_lint [1];
- caller.index = D_mess_lint [2];
-
- /* Set up D_first_msg */
- D_first_msg = FALSE;
-
- /* Get the return message type, and return it */
- return (D_mess_lint [4]);
- }
-
- void D_lib_cpr_f_init (le, return_type)
- int return_type;
- int le;
-
- {
- /* Construct the new message header */
- D_mess_lint [1] = le;
- D_mess_lint [0] = 0;
-
- /* Setup D_buf and D_rem */
- D_buf = (char *) (&D_mess_lint[2]);
- D_rem = D_MAX_MESS - 2 * sizeof (long int);
-
- /* Setup D_first_msg */
- D_first_msg = TRUE;
-
- /* Use the caller variable to set up the return address */
- D_node = D_env_lookup[caller.name][caller.index].node;
- D_pid = D_env_lookup[caller.name][caller.index].pid;
-
- /* Set up D_main_type */
- D_main_type = return_type;
- }
-
-
-
- long int D_block_func_l (le, limit, over, ediv, emod)
- int le, limit, over, ediv, emod;
-
- {
- long int t;
-
- t = le < emod ? le * (ediv + 1) : le * ediv + emod;
- return (D_max (limit, t - over));
- }
-
- long int D_block_func_r (le, limit, over, ediv, emod)
- int le, limit, over, ediv, emod;
-
- {
- long int t;
-
- t = le < emod ? (le + 1) * (ediv + 1) : (le + 1) * ediv + emod;
- return (D_min (limit, t + over));
- }
-
-
-
- void D_lib_flush_buf ()
-
- {
- int msg_type;
-
- /* Compute the next type */
- if (D_first_msg) {
- if (D_buf - D_mess_buf == D_MAX_MESS && D_sub_type == 0)
- D_sub_type = get_type();
- D_mess_lint [0] = D_sub_type;
- msg_type = D_main_type;
- D_first_msg = FALSE;
- }
- else
- msg_type = D_sub_type;
-
- /* Send out the message */
- #if D_HOST && (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendmsg (D_ci, msg_type, D_mess_buf, (int)(D_buf - D_mess_buf),
- D_node, D_pid);
- #else
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- sendw (D_ci, msg_type, D_mess_buf, (int)(D_buf - D_mess_buf),
- D_node, D_pid);
- #else
- csend ((long)msg_type, D_mess_buf, (long)(D_buf - D_mess_buf),
- (long)D_node, (long)D_pid);
- #endif
- #endif
-
- /* Reset D_buf and D_rem */
- D_buf = D_mess_buf;
- D_rem = D_MAX_MESS;
- }
-
- void D_lib_refresh_buf ()
-
- {
- int cnt, node, pid, msg_type;
-
- /* Compute the message type */
- msg_type = (D_first_msg ? D_main_type : D_sub_type);
-
- /* Read in the next message */
- #if (D_MACH==D_SIM || D_MACH==D_CUBE)
- #if D_HOST
- D_buf = D_mess_buf;
- D_recvh (D_ci, msg_type, &D_buf, D_MAX_MESS, &cnt, &node, &pid);
- if (D_buf != D_mess_buf)
- D_mem_copy (D_mess_buf, D_buf, cnt);
- #else
- recvw (D_ci, msg_type, D_mess_buf, D_MAX_MESS, &cnt, &node, &pid);
- #endif
- #else
- crecv ((long)msg_type, D_mess_buf, (long)D_MAX_MESS);
- #endif
-
- /* Reset D_buf and D_rem */
- D_buf = D_mess_buf;
- D_rem = D_MAX_MESS;
-
- /* Update D_sub_type, if necessary */
- if (D_first_msg) {
- D_sub_type = D_mess_lint [0];
- D_first_msg = FALSE;
- }
- }
-
- void D_lib_align ()
-
- {
- int skip;
-
- /* Compute how much to skip */
- skip = D_rem % sizeof (double);
-
- /* Perform the skip */
- D_buf += skip;
- D_rem -= skip;
- }
-
-
-
- /********************************************************************
- *
- * NAME: D_from --- Returns an envvar with the name and index
- * of the last environment a message was received from.
- *
- * INPUTS:
- *
- * OUTPUTS: Returns an envvar with the name and index
- * of the last environment a message was received from.
- *
- * NOTES:
- *
- ********************************************************************/
-
- envvar D_from()
- {
- return D_snd_source;
- }
-